/*
  Example 19.1 GPS clock with MAX7219 LED display driver
 http://tronixstuff.com/tutorials > Chapter 19
 
 Based on code by Aaron Weiss of SparkFun Electronics; 
 http://bit.ly/99YnI6
 also based on code and libaries by arduiniana.org. 
 Thank you :)
 
 We are using the Sparkfun GPS shield and EM-406 GPS receiver module
 Make sure the switch on the GPS shield is set to UART
 
 */
// necessary libraries
#include <NewSoftSerial.h>
#include <TinyGPS.h>
#include <LedControl.h> //  MAX7219 library
#include <Binary.h>

// define our MAX7219 setup
LedControl lc=LedControl(9,8,7,1); // lc is our object
// necessary for use of MAX7219
// pin 9 is connected to the MAX7219 pin 1
// pin 8 is connected to the CLK pin 13
// pin 7 is connected to LOAD pin 12
// 1 as we are only using 1 MAX7219

// Define which pins you will use on the Arduino to communicate with your 
// GPS. In this case, the GPS module's TX pin will connect to the 
// Arduino's RXPIN which is pin 3.
#define RXPIN 0 //   GPS TX pin connects to Arduino D0 (thankfully by default)
#define TXPIN 1 // GPS RX pin connects to Arduino D1. You could change these if making your own hardware
#define GPSBAUD 4800 // baud rate of our EM-406 GPS module. Change for your GPS module if different

// Create an instance of the TinyGPS object
TinyGPS gps;
// Initialize the NewSoftSerial library to the pins you defined above
NewSoftSerial uart_gps(RXPIN, TXPIN);

// This is where you declare prototypes for the functions that will be 
// using the TinyGPS library.
void getgps(TinyGPS &gps);

// In the setup function, you need to initialize two serial ports; the 
// standard hardware serial port (Serial()) to communicate with your 
// terminal program and another serial port (NewSoftSerial()) for your 
// GPS.
void setup()
{
  // the zero refers to the MAX7219 number, it is zero for 1 chip
  lc.shutdown(0,false);// turn off power saving, enables display
  lc.setIntensity(0,8);// sets brightness (0~15 possible values)
  lc.clearDisplay(0);// clear screen
  uart_gps.begin(GPSBAUD); // setup sketch for data output speed of GPS module
  sayHello();
  delay(2000);
  lc.clearDisplay(0);// clear screen
  delay(500);
  saySearch(); // display until locked on satellites
}

void sayHello()
// displayes "-HELLO--"
{
  lc.clearDisplay(0);// clear screen
  lc.setRow(0,0,B00000001); // -
  lc.setRow(0,1,B00110111); // H
  lc.setRow(0,2,B01001111); // E
  lc.setRow(0,3,B00001110); // L  
  lc.setRow(0,4,B00001110); // L  
  lc.setRow(0,5,B01111110); // O  
  lc.setRow(0,6,B00000001); // -
  lc.setRow(0,7,B00000001); // -  
}

void saySearch()
// displays "SEArCH--
{
  lc.clearDisplay(0);// clear screen
  lc.setRow(0,0,B01011011); // S
  lc.setRow(0,1,B01001111); // E
  lc.setRow(0,2,B01110111); // A
  lc.setRow(0,3,B00000101); // r
  lc.setRow(0,4,B01001110); // C
  lc.setRow(0,5,B00110111); // H
  lc.setRow(0,6,B00000001); // - 
  lc.setRow(0,7,B00000001); // -  
}



// The getgps function will get and print the values we want.
void getgps(TinyGPS &gps)
{

  int year,a,t;
  byte month, day, hour, minute, second, hundredths;
  gps.crack_datetime(&year,&month,&day,&hour,&minute,&second,&hundredths);

  // correct for time zone
  hour=hour+10; // my zone is GMT +10
  if (hour>23)
  {
    hour=hour-24;
  }
  // Print data and time
  lc.setChar(0,2,'-',false);
  lc.setChar(0,5,'-',false);  

  if (hour<10)
  {
    lc.setDigit(0,0,0,false);
    lc.setDigit(0,1,hour,false);
  } 
  else if (hour>=10)
  {
    t=hour/10;
    a=int(t);

    lc.setDigit(0,0,a,false);
    t=hour%10;
    lc.setDigit(0,1,t,false);
  }
  if (minute<10)
  {
    lc.setDigit(0,3,0,false);
    lc.setDigit(0,4,minute,false);
  } 
  else if (minute>=10)
  {
    t=minute/10;
    a=int(t);
    lc.setDigit(0,3,a,false);
    t=minute%10;
    lc.setDigit(0,4,t,false);

  }
  if (second<10)
  {
    lc.setDigit(0,6,0,false);
    lc.setDigit(0,7,second,false);
  } 
  else if (second>=10)
  {
    t=second/10;
    a=int(t);
    lc.setDigit(0,6,a,false);
    t=second%10;
    lc.setDigit(0,7,t,false);
  }
}


// This is the main loop of the code. All it does is check for data on 
// the RX pin of the ardiuno, makes sure the data is valid NMEA sentences, 
// then jumps to the getgps() function.
void loop()
{
  while(uart_gps.available())     // While there is data on the RX pin...
  {
    int c = uart_gps.read();    // load the data into a variable...
    if(gps.encode(c))      // if there is a new valid sentence...
    {
      getgps(gps);         // then grab the data, and display on LCD
    }
  }
}

